package br.com.registrofinancas.adapters;

import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import br.com.registrofinancas.R;
import br.com.registrofinancas.database.MovimentosDAO;
import br.com.registrofinancas.model.MovimentationVO;
import br.com.registrofinancas.model.MovimentationVO.MovimentationIcon;
import br.com.registrofinancas.util.GregorianCalendarUtil;
import br.com.registrofinancas.view.DialogCalendarInsertItemCredito;
import br.com.registrofinancas.view.DialogCalendarInsertItemDebito;
import br.com.registrofinancas.view.TVDia;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.BaseAdapter;
import android.widget.PopupMenu;
import android.widget.PopupMenu.OnMenuItemClickListener;

public class CalendarioAdapter extends BaseAdapter implements OnClickListener, OnMenuItemClickListener{
	private Context contexto ;
	private List<GregorianCalendar> dias;
	private GregorianCalendar mesAtual;
	private GregorianCalendar diaAtual;
	private Handler handler;
	private Runnable runnableUpdateView;
	private Map<String, MovimentationIcon> diasIcons;
	private Date dia;
	private CalendarioAdapter instance;
	
	public CalendarioAdapter(Context contexto, GregorianCalendar mesAtual, Handler handler, Runnable runnableUpdateView) {
		this.contexto = contexto;
		this.mesAtual = mesAtual;
		this.handler = handler;
		this.runnableUpdateView = runnableUpdateView;
		this.diasIcons = new HashMap<String, MovimentationIcon>();
		this.instance = this;
		dias = new ArrayList<GregorianCalendar>();
		diaAtual = new GregorianCalendar();
	}
	
	public CalendarioAdapter(Context contexto, GregorianCalendar mesAtual, Handler handler) {
		this(contexto,mesAtual, handler, null);
	}
	
	@Override
	public int getCount() {
		return dias.size();
	}
	
	@Override
	public Object getItem(int position) {
		return dias.get(position);
	}
	
	@Override
	public long getItemId(int position) {
		return position;
	}
	
	@SuppressLint("InflateParams")
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		TVDia texto;
		if(null == convertView){
			LayoutInflater layout = ( LayoutInflater ) contexto.getSystemService( Context.LAYOUT_INFLATER_SERVICE ) ;
			convertView = layout.inflate(R.layout.activity_calendar_item, null);
			texto = (TVDia) convertView.findViewById(R.id.activity_calendar_item_tv_dia_calendario);
			convertView.setTag(texto);
		}else{
			texto = (TVDia) convertView.getTag(); 
		}
		texto.setText(String.valueOf(dias.get(position).get(GregorianCalendar.DAY_OF_MONTH)));
		//chama o onclick
		convertView.setOnClickListener(this);
		
		texto.setPosicao(position);		
		
		if(dias.get(position).get(GregorianCalendar.MONTH) == mesAtual.get(GregorianCalendar.MONTH)){
			texto.setTextColor(contexto.getResources().getColor(R.color.cinza_3));
		}else{
			texto.setTextColor(contexto.getResources().getColor(R.color.cinza));
		}
		
		this.setBackGround(convertView , position);
		
		return convertView;
	}
	
	public void setBackGround(View view, Integer position){
		String chaveDia = MovimentosDAO.FORMATA_DATA.format(this.dias.get(position).getTime()); 
		MovimentationIcon icon = this.diasIcons.get(chaveDia);
		if(null != icon){
			switch (icon) {
			case INCOME:
				if (GregorianCalendarUtil.comparaDias(dias.get(position), diaAtual)){
					view.setBackground(contexto.getResources().getDrawable(R.drawable.calendar_cell_select_entrada));
				}
				else{
					view.setBackground(contexto.getResources().getDrawable(R.drawable.calendar_cell_entrada));
				}				
				//view.setBackground(contexto.getResources().getDrawable(R.drawable.calendar_cell_entrada));
				break;
			case OUTCOME:
				//view.setBackgroundColor(contexto.getResources().getColor(android.R.color.holo_red_dark));
				if (GregorianCalendarUtil.comparaDias(dias.get(position), diaAtual)){
					view.setBackground(contexto.getResources().getDrawable(R.drawable.calendar_cell_select_saida));
				}
				else{
					view.setBackground(contexto.getResources().getDrawable(R.drawable.calendar_cell_saida));
				}				
				//view.setBackground(contexto.getResources().getDrawable(R.drawable.calendar_cell_saida));
				break;
			case INCOME_OUTCOME:
				//view.setBackgroundColor(contexto.getResources().getColor(android.R.color.holo_blue_dark));
				if (GregorianCalendarUtil.comparaDias(dias.get(position), diaAtual)){
					view.setBackground(contexto.getResources().getDrawable(R.drawable.calendar_cell_select_entrada_saida));
				}
				else{
					view.setBackground(contexto.getResources().getDrawable(R.drawable.calendar_cell_entrada_saida));
				}				
				//view.setBackground(contexto.getResources().getDrawable(R.drawable.calendar_cell_entrada_saida));
				break;				
			default:
				if (GregorianCalendarUtil.comparaDias(dias.get(position), diaAtual)){
					view.setBackground(contexto.getResources().getDrawable(R.drawable.calendar_cell_select));
				}
				else{
					view.setBackground(contexto.getResources().getDrawable(R.drawable.calendar_cell));
				}				
				break;
			}
		}else{
			if (GregorianCalendarUtil.comparaDias(dias.get(position), diaAtual)){
				view.setBackground(contexto.getResources().getDrawable(R.drawable.calendar_cell_select));
			}
			else{
				view.setBackground(contexto.getResources().getDrawable(R.drawable.calendar_cell));
			}			
		}		
	}
	
	public MovimentationIcon getIconDoDia(List<MovimentationVO> lista){
		return null;
	}

	@Override
	public void onClick(View view) {
		TVDia diaView = (TVDia) view.getTag();
		dia = dias.get(diaView.getPosicao()).getTime();
		PopupMenu popupMenu = new PopupMenu(contexto, view);
		popupMenu.setOnMenuItemClickListener(this);
		popupMenu.inflate(R.menu.activity_calendar_popup_menu);
		popupMenu.show();		
	}
	
	@Override
	public boolean onMenuItemClick(MenuItem item) {
		Dialog dialog;
		switch (item.getItemId()) {
		case R.id.activity_calendar_popup_menu_credito:
			dialog = new DialogCalendarInsertItemCredito(contexto, dia, handler, runnableUpdateView, instance);
			dialog.show();
			return true;
		case R.id.activity_calendar_popup_menu_dedito:
			dialog = new DialogCalendarInsertItemDebito(contexto, dia, handler, runnableUpdateView, instance);
			dialog.show();
			return true;
		default:
			return false;
		}		

	}	
	
	public void preencheDias(){
		GregorianCalendar mesAnterior = getMesAnt(mesAtual);
		int qtdeSemanas = mesAtual.getActualMaximum( GregorianCalendar.WEEK_OF_MONTH );
		int maxDias = qtdeSemanas * 7;
		GregorianCalendar mesAux = (GregorianCalendar) mesAtual.clone();
		mesAux.set(GregorianCalendar.DAY_OF_MONTH, 1);
		int primeiroDiaMes = mesAux.get( GregorianCalendar.DAY_OF_WEEK );
		int primeiroDiaCalendario = getUltDiaMes(mesAnterior) - ( primeiroDiaMes - 1 );
		GregorianCalendar diaAtual =  (GregorianCalendar) mesAnterior.clone( );
		
		MovimentosDAO movimentosDAO = new MovimentosDAO(contexto);
		
		diaAtual.set( GregorianCalendar.DAY_OF_MONTH, primeiroDiaCalendario + 1);
		dias.clear( );
		this.diasIcons.clear();
		MovimentationIcon iconDia;

		for (int n = 0; n < maxDias; n++){
			dias.add( (GregorianCalendar) diaAtual.clone() );
			
			iconDia = movimentosDAO.getMovimentationIconPorDia(diaAtual.getTime());
			this.diasIcons.put(MovimentosDAO.FORMATA_DATA.format(diaAtual.getTime()), iconDia);
			
			diaAtual.add( GregorianCalendar.DATE, 1 );
		}
		
		if(null != runnableUpdateView){
			handler.post(runnableUpdateView);
		}
	}
	
	
	private GregorianCalendar getMesAnt(GregorianCalendar mes){
		GregorianCalendar mesRetorno = (GregorianCalendar) mes.clone();
		if (mes.get( GregorianCalendar.MONTH ) == mes.getActualMinimum( GregorianCalendar.MONTH )) {
			mesRetorno.set( ( mes.get( GregorianCalendar.YEAR ) - 1 ), mes.getActualMaximum( GregorianCalendar.MONTH ), 1) ;
		}
		else {
			mesRetorno.set( GregorianCalendar.MONTH, mes.get( GregorianCalendar.MONTH ) - 1) ;
		}
		return mesRetorno;
	}
	
	private int getUltDiaMes(GregorianCalendar data){
		return data.getActualMaximum( GregorianCalendar.DAY_OF_MONTH );
	}
	
	public GregorianCalendar getDiaAtual() {
		return diaAtual;
	}

	public void setDiaAtual(GregorianCalendar diaAtual) {
		this.diaAtual = diaAtual;
	}
	
}